# -*- coding: utf-8 -*-

# Author : 'hxc'

# Time: 2018/12/20 9:16 AM

# File_name: 'return_report_name.py'



import re
import time
from lxml import etree
from itertools import combinations


class Return_Report_Name(object):
    """
    Describe: A class that returns a list of report names.
    """
    def __init__(self, xml_path, user_path, number):
        """

        :param xml_path: xml文件所在路径
        :param user_path: 用户问题路径list
        :param number: 减少组合数量开关，值越大耗越少。一般取3，就可以认为第三问才有可能出报告，前2问不会出报告。
        """

        self.xml_path = xml_path
        self.user_path = user_path
        self.number = number

    def __judge_is_multi_select(self):
        """
        判断是否有多选
        :return:
        """
        for each_path in self.user_path:
            if type([]) == type(each_path):
                return True

    def __generate_question_digital_list(self):
        """
        生成问题数字list
        :return:
        """
        all_xpath_list = []
        length = len(self.user_path)
        temp_list = list(range(length))
        print("由问题路径产生的数字list:", temp_list)
        for j in range(2, length + 1):
            for k in (list(combinations(temp_list, j))):
                all_xpath_list.append(k)
        return all_xpath_list

    def __judge_tuple(self, tuple):
        """
        判断问句路径是否连续或者允许跳问。
        :param tuple:
        :return:
        """
        flag = []
        for i in range(len(tuple) - 1):
            if tuple[i + 1] - tuple[i] <= self.number:
                flag.append('0')

            else:
                flag.append('1')

        return flag

    def __user_path2string(self, each_question):
        """
        获取每一问句的xpath表达式.
        :param each_question: 其类型是个dict
        :return:
        """
        if type(each_question['item']) == type([]):
            print('here-----')
            question_xpath = '/node[@item=' + '\"' + '||'.join(each_question['item']) + '\"' + ']'
            print('question_xpath', question_xpath)
        else:
            question_xpath = '/node[@item=' + '\"' + each_question['item'] + '\"' + ']'
        return question_xpath


    def __do_first_combine_string(self,tuple):
        """
        只产生多选第一个问题的xpath
        :param tuple:
        :return:
        """
        number_list = []
        temp_string = ''
        for i in tuple:
            if type(self.user_path[i]) == type({}):
                temp_string += self.__user_path2string(self.user_path[i])
            else:
                number_list.append(i)
                temp_string += self.__user_path2string(self.user_path[i][0])

        return (number_list, temp_string)

    def get_multi_report_name(self):
        """
        获取多选的报告名字list
        :return:
        """
        name_list = []
        xpath_list = []
        question_digital_list = self.__generate_question_digital_list()
        xml_tree = etree.parse(self.xml_path)
        for i in question_digital_list:
            flag = self.__judge_tuple(i)
            if '1' not in flag and i[0] == 0 and i[1] == 1 and len(i)>2:
                #print(i)
                id_list, str = self.__do_first_combine_string(i)
                #print(id_list)
                for id in id_list:
                    first_xpath = self.__user_path2string(self.user_path[id][0])
                    for j in self.user_path[id]:
                        temp_string = self.__user_path2string(j)
                        new_string = str.replace(first_xpath, temp_string)

                        element = xml_tree.xpath('/' + new_string + '/report')
                        if element:
                            print('xpath:', new_string)
                            xpath_list.append(new_string)
                            for child in element:

                                print('report:', child.text + '.html')
                                print(" ")
                                name_list.append(child.text + '.html')
        return name_list, xpath_list

    def get_one_report_name(self):
        """
        获取单选报告的名字
        :return:
        """
        name_list = []
        xpath_list = []
        xpath_string = '/'
        for each_question in self.user_path:
            each_pathstring = self.__user_path2string(each_question)
            xpath_string = xpath_string + each_pathstring
        print(" ")
        print("xpath的表达式是：", xpath_string)
        xml_tree = etree.parse(self.xml_path)
        element = xml_tree.xpath(xpath_string + '/report')
        xpath_list.append(xpath_string)
        print('其文档为：')
        for child in element:
            name_list.append(child.text + '.html')
            print(name_list)
        return name_list, xpath_list

    # def __judge_is_in(self, xpath_list, each_question):
    #     """
    #     判断xpath每个元素是否在每个问句里
    #     :return:
    #     """
    #
    #     for each_xpath in xpath_list:
    #         print(each_xpath)
    #         pattern = re.compile(r'=".*?"')
    #         context = re.findall(pattern, each_xpath)
    #         for i in context:
    #             i = i.replace('=', '')
    #             i = i.replace('"', '')
    #             if i == each_question['item']:
    #                 return True
    def __do_which_question(self, each_xpath):
        """
        获取xpath对应的那个问题
        :param each_xpath:
        :return:
        """
        temp_question = []
        pattern = re.compile(r'=".*?"')
        context = re.findall(pattern, each_xpath)
        for i in context:
            i = i.replace('=', '')
            i = i.replace('"', '')
            for each_question in self.user_path:
                if type(each_question) == type({}):
                    if i == each_question['item']:
                        temp_question.append(each_question)
                else:
                    for j in each_question:
                        if i == j['item']:
                            temp_question.append(j)
        print(temp_question)
        return temp_question

    def __get_report_question(self, xpath_list):
        """
        获取搜到文件的用户问题
        :param xpath_list:
        :return:
        """
        all_user_path = []

        for each_xpath in xpath_list:
            each_question = self.__do_which_question(each_xpath)
            all_user_path.append(each_question)
        return all_user_path

    def get_report_name(self):
        """
        获取报告名的api
        :return:
        """
        start_time = time.time()
        print('*************** Get Report Name Starting ***************')
        if self.__judge_is_multi_select():

            #返回多选报告name_list
            report_name_list, xpath_list = self.get_multi_report_name()
            report_name_list_question = self.__get_report_question(xpath_list)
            print(report_name_list_question)
            print(" ")
            print('耗时为：{:0.2f}s'.format(time.time() - start_time))
            print('*************** Get Report Name Finishing ***************')
            return report_name_list, report_name_list_question
        else:

            #返回单选报告name_list
            report_name_list, report_name_list_question = self.get_one_report_name()
            print('耗时为：{:0.2f}s'.format(time.time() - start_time))
            print('*************** Get Report Name Finishing ***************')
            return report_name_list, report_name_list_question



if __name__ == '__main__':

    #多选测试
    user_path1 = {'iw': '4', 'id_question': '你是男方还是女方？', 'item': '男方', 'flag': 'done'}
    user_path2 = [{'iw': '2', 'id_question': '你想咨询小孩的什么问题？', 'item': '你想把小孩的抚养权要回来 你觉得小孩由你抚养照顾更好', 'flag': 'done'},
                  {'iw': '2', 'id_question': '你想咨询小孩的什么问题？', 'item': '小孩抚养费的问题', 'flag': 'done'}]
    user_path3 = {'iw': '4', 'id_question': '你们是怎么离婚的？', 'item': '协议离婚', 'flag': 'done'}
    user_path4 = {'iw': '4', 'id_question': '你要变更的小孩现在实际上是谁在抚养照顾？', 'item': '你', 'flag': 'done'}
    user_path5 = [{'iw': '2', 'id_question': '你们有以下哪些情形存在？', 'item': '孩子8周岁了想和你一起生活 这里小孩必须满8岁', 'flag': 'done'},
                  {'iw': '2', 'id_question': '你们有以下哪些情形存在？', 'item': '女方再婚对子女身心健康存在不利影响', 'flag': 'done'}]
    user_path6 = [{'iw': '2', 'id_question': '具体是抚养费的什么问题？', 'item': '你要变更小孩的抚养费 你觉得抚养费不合理', 'flag': 'done'},
                  {'iw': '2', 'id_question': '具体是抚养费的什么问题？', 'item': '女方不支付小孩的抚养费', 'flag': 'done'}]
    user_path7 = {'iw': '4', 'id_question': '你想咨询以下什么问题？', 'item': '你想增加小孩的抚养费', 'flag': 'done'}
    user_path8 = [{'iw': '2', 'id_question': '你想增加小孩抚养费的原因是什么？', 'item': '小孩因上学、患病等原因 所需费用已超过原定数额', 'flag': 'done'},
                  {'iw': '2', 'id_question': '你想增加小孩抚养费的原因是什么？', 'item': '女方收入明显增加 以及其他正当理由', 'flag': 'done'}]
    user_path = [user_path1, user_path2, user_path3, user_path4, user_path5, user_path6, user_path7, user_path8]

    generator = Return_Report_Name('./data/离婚后小孩问题_tree.xml', user_path, 3)
    generator.get_report_name()


